package com.cooud.gateway.predicates;

import jakarta.validation.constraints.NotEmpty;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: DongGuoZhen
 * @Date: 2025/03/19/13:09
 * @Description:
 */
//自定义断言工厂类，继承AbstractRoutePredicateFactory类，实现apply方法，返回一个GatewayPredicate对象，用于判断请求是否满足条件
//该类用于判断请求是否包含指定参数，且参数的值与配置的value值相同
//该类可以配置在路由规则中，用于匹配请求参数中的指定参数值
@Component
public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory<VipRoutePredicateFactory.Config> {


    public VipRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("param", "value");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
//                localhost/serach?q=haha&user=dgz
                ServerHttpRequest request = serverWebExchange.getRequest();
                String first = request.getQueryParams().getFirst(config.getParam()); // 拿到请求参数中的第一个值
                return StringUtils.hasText(first) && first.equals(config.getValue());
            }
        };
    }

    @Validated
    public static class Config {
        @NotEmpty
        private String param;

        public @NotEmpty String getParam() {
            return param;
        }

        public void setParam(@NotEmpty String param) {
            this.param = param;
        }

        public @NotEmpty String getValue() {
            return value;
        }

        public void setValue(@NotEmpty String value) {
            this.value = value;
        }

        @NotEmpty
        private String value;

    }


}
